package fr.cephb.operonj.tools.cmdline;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Reader;

import javax.xml.stream.XMLStreamException;


import com.sleepycat.je.DatabaseException;

import fr.cephb.operonj.core.bio.ChromInfo;
import fr.cephb.operonj.core.db.database.ChromDB;
import fr.cephb.operonj.core.db.database.GenomicSeqDB;
import fr.cephb.operonj.core.db.key.BuildChrom;

public class FastaCmd extends AbstractApplication
	{
	private File fileOut=null;
	private Integer buildId=null;
	private Integer chromId=null;
	private Integer startIndex=null;
	private Integer endIndex=null;
	
	@Override
	protected void usage(PrintStream out)
		{
		super.usage(out);
		out.println("Options:");
		out.println(" -o <fileout>");
		out.println(" -b <build-id> optional");
		out.println(" -c <chrom-id> required");
		out.println(" -s <start> 0 based. inclusive. optional");
		out.println(" -e <end> 0 based. exclusive. optional");
		}
	
	@Override
	protected int processArg(String[] args, int optind)
		{
		int n= super.processArg(args, optind);
		if(n!=-1) return n;
		if(args[optind].equals("-o"))
			{
			this.fileOut=new File(args[++optind]);
			return optind;
			}
		else if(args[optind].equals("-b"))
			{
			this.buildId=new Integer(args[++optind]);
			return optind;
			}
		else if(args[optind].equals("-c"))
			{
			this.chromId=new Integer(args[++optind]);
			return optind;
			}
		else if(args[optind].equals("-s"))
			{
			this.startIndex=new Integer(args[++optind]);
			return optind;
			}
		else if(args[optind].equals("-e"))
			{
			this.endIndex=new Integer(args[++optind]);
			return optind;
			}
		return -1;
		}
	
	private int run(String args[]) throws IOException,DatabaseException,XMLStreamException
		{
		int optind= processArgs(args);
		if(optind!=args.length)
			{
			System.err.println("too many arguments");
			return -1;
			}
		
		if(this.buildId==null)
			{
			System.err.println("undefined build");
			return -1;
			}
		
		if(this.chromId==null)
			{
			System.err.println("undefined chromId");
			return -1;
			}
		
		if(startIndex==null)
			{
			startIndex=0;
			}
		
		
		
		PrintWriter w=new PrintWriter(
			fileOut==null?
			System.out:
			new FileOutputStream(this.fileOut)
			);
		
		open();
		
		ChromDB chromDB =new ChromDB(getEnvironment(), null, null, null);
		BuildChrom bc= new BuildChrom(this.buildId, this.chromId);
		ChromInfo info=chromDB.get(null, bc);
		if(info==null)
			{
			throw new IllegalArgumentException("Not found "+bc);
			}
		
		GenomicSeqDB seqDB= new GenomicSeqDB(getEnvironment(), null, null, null);
		Reader reader=seqDB.getReader(null, this.buildId, this.chromId, this.startIndex);
		
		int c=0;
		int count=0;
		w.print(">"+info.getName());
		while((c=reader.read())!=-1)
			{
			if( endIndex!=null &&
				startIndex+count >= endIndex)
				{
				break;
				}
			if(count%60==0) w.println();
			w.print((char)c);
			++count;
			}
		
		w.println();
		w.flush();
		w.close();
		
		if(seqDB!=null) seqDB.close();
		if(chromDB!=null) chromDB.close();
		close();
		return 0;
		}
	
	
	public static void main(String[] args)
		{
		try
			{
			FastaCmd app= new FastaCmd();
			app.run(args);
			}
		catch (Exception err)
			{
			err.printStackTrace();
			}
		}
	}
